/*
 * meituan.com Inc.
 * Copyright (c) 2010-2018 All Rights Reserved.
 */

import java.util.concurrent.locks.AbstractQueuedSynchronizer;

/**
 * <p>
 *
 * </p>
 * @author LvJing
 * @version $Id:TwinsLock.java v1.0 2018/7/23 下午2:10 LvJing Exp $
 */
public class TwinsLock {

    private final Sync sync = new Sync(2);

    /**
     * 共享锁：只能让最对两个线程同时拥有锁，其他获取锁的均会被阻塞
     */
    static final class Sync extends AbstractQueuedSynchronizer {

        Sync(int count) {
            if (count < 0) {
                throw new IllegalArgumentException("count");
            }
            setState(count);
        }

        @Override
        protected int tryAcquireShared(int arg) {
            // 共享式获取锁
            for (;;) {
                int currentState = super.getState();
                int newState = currentState - arg;

                if (newState < 0) {
                    return newState;
                }
                if (super.compareAndSetState(currentState, newState)) {
                    return newState;
                }
            }
        }

        @Override
        protected boolean tryReleaseShared(int arg) {
            // 共享式释放锁
            for (;;) {
                int currentState = super.getState();
                int newState = currentState + arg;
                if (compareAndSetState(currentState, newState)) {
                    return true;
                }
            }
        }
    }

    public void lock() {
        sync.acquireShared(1);
    }

    public void unlock() {
        sync.releaseShared(1);
    }
}
